home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / drvrs / xgav210.zip / XGAPCDOS / XGADEMO.C < prev    next >
C/C++ Source or Header  |  1993-07-21  |  27KB  |  813 lines

  1.  
  2.     /********************************************************/
  3.     /*                                                      */
  4.     /*                                                      */
  5.     /*            XGA Adapter Demonstration Program         */
  6.     /*                                                      */
  7.     /*     Compile this module, then link to CALLAFI.OBJ    */
  8.     /*                                                      */
  9.     /*               Version 1.01  7/30/91                  */
  10.     /*                                                      */
  11.     /********************************************************/
  12.  
  13.  
  14.  
  15. /**************************************************/
  16. /*                                                */
  17. /*          Include files                         */
  18. /*                                                */
  19. /**************************************************/
  20.  
  21.    /* C library includes                          */
  22.  
  23. #include <stdio.h>
  24. #include <malloc.h>
  25. #include <string.h>
  26. #include <fcntl.h>
  27. #include <sys\types.h>
  28. #include <sys\stat.h>
  29. #include <io.h>
  30. #include <conio.h>
  31. #include <dos.h>
  32. #include <time.h>
  33. #include <stdlib.h>
  34. #include <process.h>
  35.  
  36.  
  37.  
  38.    /* Adaper interface include file               */
  39.  
  40. #include <ibmafi.h>
  41.  
  42. #undef  toupper
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49. /**************************************************/
  50. /*                                                */
  51. /*           Global defines and variables         */
  52. /*                                                */
  53. /**************************************************/
  54.  
  55.     #define TRUE   1
  56.     #define FALSE  0
  57.  
  58.     #define byte              unsigned char
  59.     #define word              unsigned int
  60.  
  61.     #define   ENTER   0xD
  62.  
  63.  
  64.  
  65.     /* Colors for non standard palette            */
  66.  
  67.     #define   GREY              2
  68.     #define   WHITE             3
  69.     #define   CYAN              4
  70.     #define   LT_CYAN           5
  71.     #define   BROWN             6
  72.     #define   YELLOW            7
  73.     #define   BLUE              8
  74.     #define   LT_BLUE           9
  75.     #define   RED            0x0a
  76.     #define   LT_RED         0x0b
  77.     #define   MAGENTA        0x0c
  78.     #define   LT_MAGENTA     0x0d
  79.     #define   GREEN          0x0e
  80.     #define   LT_GREEN       0x0f
  81.  
  82.  
  83.     /* Data for small ( 640 * 480 screen resolution ) shapes                 */
  84.  
  85.                  /* color    length                 coordinate pairs         */
  86.   int            /*         ( bytes )                                        */
  87.     quad1_s[]  = { CYAN,       16,   98, 141,  107, 127,  232, 343,  214, 343 },
  88.     quad2_s[]  = { LT_CYAN,    16,  110, 121,  118, 106,  255, 343,  237, 343 },
  89.     quad3_s[]  = { BROWN,      16,  178, 200,  295,   0,  312,   0,  187, 216 },
  90.     quad4_s[]  = { YELLOW,     16,  190, 221,  318,   0,  335,   0,  199, 236 },
  91.     quad5_s[]  = { BLUE,       16,  284,  96,  514,  96,  523, 112,  275, 112 },
  92.     quad6_s[]  = { LT_BLUE,    16,  273, 117,  526, 117,  535, 133,  263, 133 },
  93.     quad7_s[]  = { RED,        16,  408, 139,  426, 139,  542, 337,  533, 353 },
  94.     quad8_s[]  = { LT_RED,     16,  385, 139,  403, 139,  530, 358,  521, 373 },
  95.     quad9_s[]  = { MAGENTA,    16,  454, 266,  463, 282,  348, 479,  330, 479 },
  96.     quad10_s[] = { LT_MAGENTA, 16,  442, 246,  451, 261,  325, 479,  307, 479 },
  97.     quad11_s[] = { GREEN,      16,  116, 367,  366, 367,  357, 382,  124, 382 },
  98.     quad12_s[] = { LT_GREEN,   16,  104, 348,  376, 348,  369, 362,  113, 362 },
  99.     hex_s[]    = { GREY,       24,  201, 240,  260, 139,  380, 139,  439, 240,
  100.                                                          380, 343,  260, 343 };
  101.  
  102.     int * small_shapes[] =  {  quad1_s,
  103.                                quad2_s,
  104.                                quad3_s,
  105.                                quad4_s,
  106.                                quad5_s,
  107.                                quad6_s,
  108.                                quad7_s,
  109.                                quad8_s,
  110.                                quad9_s,
  111.                                quad10_s,
  112.                                quad11_s,
  113.                                quad12_s,
  114.                                hex_s     };
  115.  
  116.  
  117.     /* Data for large ( 1024 * 768 screen resolution ) shapes                */
  118.  
  119.                  /* color    length                 coordinate pairs         */
  120.   int            /*         ( bytes )                                        */
  121.     quad1_l[]  = { CYAN,       16,  159, 228,  172, 205,  371, 548,  344, 548 };
  122.     quad2_l[]  = { LT_CYAN,    16,  177, 196,  191, 172,  409, 548,  381, 548 };
  123.     quad3_l[]  = { BROWN,      16,  286, 320,  469, 0,    497, 0  ,  300, 343 };
  124.     quad4_l[]  = { YELLOW,     16,  304, 351,  506, 0,    535, 0  ,  319, 375 };
  125.     quad5_l[]  = { BLUE,       16,  454, 156,  824, 156,  837, 180,  439, 180 };
  126.     quad6_l[]  = { LT_BLUE,    16,  434, 188,  842, 188,  856, 212,  421, 212 };
  127.     quad7_l[]  = { RED,        16,  654, 220,  681, 220,  865, 540,  851, 565 };
  128.     quad8_l[]  = { LT_RED,     16,  617, 220,  644, 220,  846, 573,  832, 597 };
  129.     quad9_l[]  = { MAGENTA,    16,  723, 424,  738, 448,  551, 767,  527, 767 };
  130.     quad10_l[] = { LT_MAGENTA, 16,  705, 392,  719, 416,  516, 767,  488, 767 };
  131.     quad11_l[] = { GREEN,      16,  188, 588,  583, 588,  569, 612,  202, 612 };
  132.     quad12_l[] = { LT_GREEN,   16,  169, 556,  602, 556,  588, 580,  183, 580 };
  133.     hex_l[]    = { GREY,       24,  323, 383,  417, 220,  607, 220,  701, 383,
  134.                                                           607, 548,  417, 548 };
  135.  
  136.     int * large_shapes[] =  {  quad1_l,
  137.                                quad2_l,
  138.                                quad3_l,
  139.                                quad4_l,
  140.                                quad5_l,
  141.                                quad6_l,
  142.                                quad7_l,
  143.                                quad8_l,
  144.                                quad9_l,
  145.                                quad10_l,
  146.                                quad11_l,
  147.                                quad12_l,
  148.                                hex_l     };
  149.  
  150.     #define NUM_SHAPES   sizeof( large_shapes ) / sizeof( large_shapes[ 0 ] )
  151.  
  152.  
  153.  
  154.     static char palette_data[][4] = {
  155.  
  156.         /*      R      B      G                               */
  157.  
  158.                 0,     0 ,    0,   0,       /* black      0    */
  159.              0x24,  0x24 , 0x24,   0,       /* lt black   1    */
  160.              0x94,  0x94 , 0x94,   0,       /* grey       2    */
  161.              0xfc,  0xfc , 0xfc,   0,       /* lt white   3    */
  162.                 0,  0x70 , 0x70,   0,       /* cyan       4    */
  163.                 0,  0xfc , 0xfc,   0,       /* lt cyan    5    */
  164.              0x70,     0 , 0x48,   0,       /* brown      6    */
  165.              0xfc,  0x24 , 0xfc,   0,       /* yellow     7    */
  166.                 0,  0x70 ,    0,   0,       /* blue       8    */
  167.                 0,  0xfc ,    0,   0,       /* lt blue    9    */
  168.              0x70,     0 ,    0,   0,       /* red        a    */
  169.              0xfc,  0x24 , 0x24,   0,       /* lt red     b    */
  170.              0x70,  0x70 ,    0,   0,       /* magenta    c    */
  171.              0xb0,  0xfc ,    0,   0,       /* lt magenta d    */
  172.                 0,     0 , 0x70,   0,       /* green      e    */
  173.              0x24,  0x24 , 0xfc,   0,       /* lt green   f    */
  174.                 0,     0 ,    0,   0,       /* 2 spare to allow for shuffling */
  175.                 0,     0 ,    0,   0
  176.             };
  177.  
  178.  
  179.     /* linked list of message file lines                           */
  180.  
  181.     typedef struct LINE_S
  182.                    {
  183.                        struct LINE_S * next_ptr;
  184.                        char  line[ 1 ];
  185.                    } LINE_T;
  186.  
  187.  
  188.  
  189.     #define   DEMO_LOGO_MSG     0
  190.     #define   NO_ADAPTER_MSG    1
  191.     #define   OPEN_FAILED_MSG   2
  192.     #define   NO_FONT_MSG       3
  193.  
  194.     char * demo_files[] = { "xgademo0.msg",
  195.                             "xgademo1.msg",
  196.                             "xgademo2.msg",
  197.                             "xgademo3.msg" };
  198.  
  199.  
  200.     static char xga_path[ 120 ];
  201.     static char file_path[ 120 ];
  202.  
  203.     static int cell_height;
  204.  
  205.     static char far * state_buf;
  206.  
  207.  
  208.  
  209.  
  210.  
  211. /**************************************************/
  212. /*                                                */
  213. /*           XGA interface parameter blocks       */
  214. /*                                                */
  215. /**************************************************/
  216.  
  217.     HQDPS_DATA    hqdps_data     = { 14 };             /* Query state        */
  218.     HSPAL_DATA   * save_pal_data;                      /* save palette       */
  219.     HOPEN_DATA    hopen_data     = { 3, 0, 0, 0 };     /* open adapter       */
  220.     HCLOSE_DATA   hclose_data    = { 1, 0 };           /* close adapter      */
  221.     HINIT_DATA    hinit_data     = { 2, 0 };           /* initialise adapter */
  222.     HQMODE_DATA   hqmode_data    = { 18 };             /* query mode         */
  223.     HEAR_DATA     hear_data      = { 1, 0 };           /* end area           */
  224.     HSCOL_DATA    hscol_data     = { 4, 0 };           /* set colour         */
  225.     HINT_DATA     hint_data      = { 4, 0x80000000 };  /* wait for event     */
  226.     HSCS_DATA     hscs_data      = { 4, 0 };           /* set character set  */
  227.     HCHST_DATA( 128 ) hchst_data;                      /* write string       */
  228.  
  229.     HLDPAL_DATA   hldpal_data    = { 10, 0, 0, 0, 16,  /* load palette       */
  230.                                            ( byte far * )palette_data };
  231.  
  232.  
  233.  
  234.  
  235.  
  236. /**************************************************/
  237. /*                                                */
  238. /*           Function declarations                */
  239. /*                                                */
  240. /**************************************************/
  241.  
  242. void main( int, char ** );
  243.  
  244. static void    get_xga_path( int, char ** );
  245. static void    init_adapter( void );
  246. static void    draw_shapes( void );
  247. static void    run_demo( void );
  248. static LINE_T * get_msg( int );
  249. static void    error_exit( int, int );
  250.  
  251. struct CharSetDef *  load_font( char * );
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258. /*****************************************************************************/
  259. /*                                                                           */
  260. /*                                                                           */
  261. /*                                main                                       */
  262. /*                                ════                                       */
  263. /*                                                                           */
  264. /*****************************************************************************/
  265.  
  266. void main( argc, argv )
  267.  
  268.     int      argc;
  269.     char  ** argv;
  270.  
  271. {
  272.     /*-----------------------------------------------------------*/
  273.  
  274.     get_xga_path( argc, argv );
  275.  
  276.     init_adapter();
  277.  
  278.     draw_shapes();
  279.  
  280.     run_demo();
  281. }
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.     /************************************************************/
  290.     /*                                                          */
  291.     /*                                                          */
  292.     /*                     get_xga_path                         */
  293.     /*                     ════════════                         */
  294.     /*                                                          */
  295.     /*  Create a directory path where message files should be.  */
  296.     /*                                                          */
  297.     /************************************************************/
  298.  
  299. void get_xga_path( argc, argv )
  300.  
  301.     int     argc;
  302.     char ** argv;
  303. {
  304.     /*----------------------------------------------------------*/
  305.  
  306.     /* If a parameter is passed to this program, it should      */
  307.     /* represent the directory where the XGA Adapter software   */
  308.     /* was installed.                                           */
  309.  
  310.     if ( argc >= 2 )
  311.     {
  312.         strcpy( xga_path, argv[ 1 ] );
  313.  
  314.  
  315.         /* add \ to end of string                               */
  316.  
  317.         if ( xga_path[ strlen( xga_path ) - 1 ] != '\\' )
  318.             strcat( xga_path, "\\" );
  319.     }
  320.     else
  321.     {
  322.         strcpy( xga_path, argv[ 0 ] );
  323.  
  324.  
  325.         /* remove name of this program from path                */
  326.  
  327.         *( strrchr( xga_path, '\\' ) + 1 ) = '\0';
  328.     }
  329. }
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.     /************************************************************/
  337.     /*                                                          */
  338.     /*                                                          */
  339.     /*                     init_adapter                         */
  340.     /*                     ════════════                         */
  341.     /*                                                          */
  342.     /*        Open and Initialise XGA adapter                   */
  343.     /*                                                          */
  344.     /************************************************************/
  345.  
  346. void init_adapter()
  347.  
  348. {
  349.     char     * font_file;
  350.  
  351.     /*----------------------------------------------------------*/
  352.  
  353.     if ( getafi() == NULL )
  354.         error_exit( NO_ADAPTER_MSG, 0 );
  355.  
  356.  
  357.     /* Allocate Adapter interface task dependent buffer         */
  358.  
  359.     HQDPS( &hqdps_data );
  360.     state_buf = ( char far * ) malloc( hqdps_data.size + 15 );
  361.  
  362.  
  363.     /* Allocate palette save restore buffer                     */
  364.  
  365.     save_pal_data =  malloc( hqdps_data.palbufsize + 2 );
  366.     save_pal_data->length = hqdps_data.palbufsize;
  367.  
  368.  
  369.     /* save palette                                             */
  370.  
  371.     HSPAL( save_pal_data );
  372.  
  373.  
  374.     /* Attempt to open XGA adapter in mode 0 ( 1024 * 768 ). If the attached */
  375.     /* monitor does not support this mode, or there is insufficient vram,    */
  376.     /* then the XGA adapter may open in another mode.                        */
  377.  
  378.     HOPEN( &hopen_data );
  379.  
  380.     if ( hopen_data.iflags )
  381.         error_exit( OPEN_FAILED_MSG,
  382.                     ( byte )hopen_data.iflags );
  383.  
  384.  
  385.     /* Make sure that task dependent buffer is situated on a    */
  386.     /*                                       16 byte boundary.  */
  387.  
  388.     hinit_data.segment = FP_SEG( state_buf )
  389.                                         + ( ( FP_OFF( state_buf ) + 15) >> 4 );
  390.  
  391.     /* initialise XGA adapter                                   */
  392.  
  393.     HINIT( &hinit_data );
  394.  
  395.  
  396.     /* load palette for demo                                    */
  397.  
  398.     HLDPAL( palette_data );
  399.  
  400.  
  401.     /* Find out mode and associated data                        */
  402.  
  403.     HQMODE( &hqmode_data );
  404.  
  405.  
  406.     /* Select a font depending on character size for mode       */
  407.  
  408.     switch ( hqmode_data.ac_h )
  409.     {
  410.         case 14:
  411.             font_file = "stan0814.fnt";
  412.             break;
  413.  
  414.         case 15:
  415.             font_file = "stan0715.fnt";
  416.             break;
  417.  
  418.         case 20:
  419.             font_file = "stan1220.fnt";
  420.             break;
  421.  
  422.         case 23:
  423.             font_file = "stan1223.fnt";
  424.             break;
  425.      }
  426.  
  427.  
  428.      /* read font definition from file, then load adapter character set */
  429.  
  430.      if ( hscs_data.address = load_font( font_file ) )
  431.          HSCS( &hscs_data );
  432.  
  433. }
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.     /************************************************************/
  441.     /*                                                          */
  442.     /*                                                          */
  443.     /*                       draw_shapes                        */
  444.     /*                       ═══════════                        */
  445.     /*                                                          */
  446.     /*   Draw all shapes in shape list, and write text in       */
  447.     /*   center of hexagon.                                     */
  448.     /*                                                          */
  449.     /************************************************************/
  450.  
  451. void draw_shapes()
  452.  
  453. {
  454.     int       offset_x = 0;
  455.     int       offset_y = 0;
  456.     int       shape_id;
  457.     int       coord_id;
  458.     int      * shape_ptr;
  459.     coord_pr * coord_ptr;
  460.     LINE_T   * line_ptr;
  461.  
  462.     /*----------------------------------------------------------*/
  463.  
  464.     /* Draw each shape                                          */
  465.  
  466.     for ( shape_id = 0; shape_id < NUM_SHAPES; ++shape_id )
  467.     {
  468.         /* if screen size > 1024 * 768, offset shapes to center of screen */
  469.  
  470.         if ( hqmode_data.width >= 1024  ||  hqmode_data.height >= 768 )
  471.         {
  472.             shape_ptr = large_shapes[ shape_id ];
  473.  
  474.             hchst_data.coord.x_coord = 323;
  475.             hchst_data.coord.y_coord = 220;
  476.  
  477.             offset_x = ( ( hqmode_data.width  - 1024 ) / 2 );
  478.             offset_y = ( ( hqmode_data.height -  768 ) / 2 );
  479.  
  480.             for ( coord_id = 0, coord_ptr = ( coord_pr * )&shape_ptr[ 2 ];
  481.                    coord_id < shape_ptr[ 1 ] / sizeof( coord_pr ); ++coord_id )
  482.             {
  483.                 coord_ptr->x_coord   += offset_x;
  484.                 coord_ptr++->y_coord += offset_y;
  485.             }
  486.         }
  487.         else
  488.         {
  489.             shape_ptr = small_shapes[ shape_id ];
  490.  
  491.             hchst_data.coord.x_coord = 201;
  492.             hchst_data.coord.y_coord = 139;
  493.         }
  494.  
  495.         /* set colour for shape                                      */
  496.  
  497.         hscol_data.index = shape_ptr[ 0 ];
  498.         HSCOL( &hscol_data );
  499.  
  500.  
  501.         /* draw shape                                                */
  502.  
  503.         HBAR();
  504.         shape_ptr++;
  505.         HLINE( shape_ptr );
  506.         HEAR( &hear_data );
  507.     }
  508.  
  509.     /* write text in bright white                                */
  510.  
  511.      hscol_data.index = WHITE;
  512.      HSCOL( &hscol_data );
  513.  
  514.  
  515.     /* write text in the middle of hexagon                           */
  516.  
  517.     if ( ( line_ptr = get_msg( DEMO_LOGO_MSG ) ) && hscs_data.address )
  518.     {
  519.         while ( line_ptr != NULL )
  520.         {
  521.             /* write each line to xga screen                         */
  522.  
  523.             hchst_data.length = sizeof(coord_pr) + strlen( line_ptr->line ) - 1;
  524.  
  525.             memcpy( hchst_data.string,
  526.                     line_ptr->line,
  527.                     strlen( line_ptr->line ) - 1 );
  528.  
  529.             HCHST( &hchst_data );
  530.  
  531.  
  532.             /* position next line down by character cell height      */
  533.  
  534.             hchst_data.coord.y_coord += cell_height;
  535.  
  536.             line_ptr = line_ptr->next_ptr;
  537.         }
  538.     }
  539. }
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.     /************************************************************/
  547.     /*                                                          */
  548.     /*                                                          */
  549.     /*                       run_demo                           */
  550.     /*                       ════════                           */
  551.     /*                                                          */
  552.     /*     Change colours of logo by rotating palette values    */
  553.     /*     once per second.                                     */
  554.     /*                                                          */
  555.     /************************************************************/
  556.  
  557. void run_demo()
  558.  
  559. {
  560.     static long time_now;
  561.     static long previous_time = 0;
  562.  
  563.     /*----------------------------------------------------------*/
  564.  
  565.     while ( ( !kbhit() ) || ( getch() != ENTER ) )
  566.     {
  567.         /* shuffle palette entries to rotate symbol             */
  568.  
  569.         memmove( palette_data[ 6 ], palette_data[ 4 ], 48 );
  570.         memmove( palette_data[ 4 ], palette_data[ 16 ], 8 );
  571.  
  572.  
  573.         /* Wait for frame flyback, the load shuffled palette    */
  574.  
  575.         HINT( &hint_data );
  576.         HLDPAL( &hldpal_data );
  577.  
  578.  
  579.         /* wait until time changes                              */
  580.  
  581.         while ( previous_time == time( &time_now ) );
  582.         previous_time = time_now;
  583.     }
  584.  
  585.     /* close adapter and restore palette                        */
  586.  
  587.     HCLOSE( &hclose_data );
  588.     HRPAL( save_pal_data );
  589. }
  590.  
  591.  
  592.  
  593.  
  594.     /************************************************************/
  595.     /*                                                          */
  596.     /*                                                          */
  597.     /*                       error_exit                         */
  598.     /*                       ══════════                         */
  599.     /*                                                          */
  600.     /*  On error : Close adapter, restore previous palette,     */
  601.     /*  then display error message on VGA screen.               */
  602.     /*                                                          */
  603.     /************************************************************/
  604.  
  605. void error_exit( msg_id, error_num )
  606.  
  607.     int      msg_id;
  608.     int      error_num;
  609. {
  610.     LINE_T * msg_ptr;
  611.  
  612.     /*----------------------------------------------------------*/
  613.  
  614.     /* close adapter and restore palette                        */
  615.  
  616.     if ( msg_id != NO_ADAPTER_MSG )
  617.     {
  618.         HCLOSE( &hclose_data );
  619.         HRPAL( save_pal_data );
  620.     }
  621.  
  622.     msg_ptr = get_msg( msg_id );
  623.  
  624.     while( msg_ptr != NULL )
  625.     {
  626.         printf( "%s", msg_ptr->line );
  627.         msg_ptr = msg_ptr->next_ptr;
  628.     }
  629.  
  630.     if ( error_num )
  631.         printf(" %2xh", error_num );
  632.  
  633.  
  634.     exit( 1 );
  635. }
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.     /************************************************************/
  643.     /*                                                          */
  644.     /*                                                          */
  645.     /*                        get_msg                           */
  646.     /*                        ═══════                           */
  647.     /*                                                          */
  648.     /*  open and read message file for particular language.     */
  649.     /*                                                          */
  650.     /************************************************************/
  651.  
  652. LINE_T * get_msg( msg_id )
  653.  
  654.     int  msg_id;
  655. {
  656.     char  * file_name;
  657.     FILE *  f_id;
  658.     LINE_T * msg_ptr;
  659.     LINE_T * new_ptr, * line_ptr;
  660.  
  661.     static char line_buf[ 128 ];
  662.  
  663.     /*----------------------------------------------------------*/
  664.  
  665.     file_name = demo_files[ msg_id ];
  666.  
  667.     msg_ptr = NULL;
  668.  
  669.     if ( ( f_id = fopen( file_name, "r" ) ) == NULL )
  670.     {
  671.         /* Can't find file in current directory so try xga path. */
  672.  
  673.         strcpy( file_path, xga_path );
  674.         strcat( file_path, file_name );
  675.  
  676.         if ( ( f_id = fopen( file_path, "r" ) ) == NULL )
  677.         {
  678.             /* Can't find file in xga path, so try \XGAPCDOS.    */
  679.  
  680.             strcpy( file_path, "\\XGAPCDOS\\" );
  681.             strcat( file_path, file_name );
  682.  
  683.             f_id = fopen( file_path, "r" );
  684.         }
  685.     }
  686.  
  687.     if ( f_id != NULL )
  688.     {
  689.         /* file opened successfully so read message              */
  690.  
  691.  
  692.         while ( fgets( line_buf, sizeof( line_buf ), f_id ) != NULL )
  693.         {
  694.             new_ptr = malloc( strlen( line_buf ) + sizeof( LINE_T ) );
  695.  
  696.             if ( msg_ptr == NULL )
  697.                 msg_ptr = line_ptr = new_ptr;
  698.             else
  699.             {
  700.                 line_ptr->next_ptr = new_ptr;
  701.                 line_ptr = new_ptr;
  702.             }
  703.  
  704.             strcpy( line_ptr->line, line_buf );
  705.         }
  706.  
  707.         /* indicate last line by NULL next ptr                    */
  708.  
  709.         line_ptr->next_ptr = NULL;
  710.  
  711.         fclose( f_id );
  712.  
  713.     }
  714.  
  715.     return  msg_ptr;
  716. }
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.     /************************************************************/
  725.     /*                                                          */
  726.     /*                                                          */
  727.     /*                       Load_font                          */
  728.     /*                       ═════════                          */
  729.     /*                                                          */
  730.     /*    Read a font file definition into memory.              */
  731.     /*                                                          */
  732.     /************************************************************/
  733.  
  734. struct CharSetDef *  load_font( font_file )
  735.  
  736.     char  * font_file;
  737. {
  738.     int           font_fid;
  739.     static char   font_path[ 120 ];
  740.     word          font_file_len;
  741.     struct FontFileDefn * ffd_ptr;
  742.     struct CharSetDef   * csd_ptr = NULL;
  743.  
  744.     /*----------------------------------------------------------*/
  745.  
  746.     /* Open font file as binary, read only                      */
  747.  
  748.     font_fid = open( font_file,  O_RDONLY | O_BINARY );
  749.  
  750.  
  751.     if ( font_fid == -1 )
  752.     {
  753.         /* Can't find file in current directory so try xga path. */
  754.  
  755.         strcpy( font_path, xga_path );
  756.         strcat( font_path, font_file );
  757.  
  758.         font_fid = open( font_path, O_RDONLY | O_BINARY );
  759.  
  760.         if ( font_fid == -1 )
  761.         {
  762.             /* Can't find file in xga path, so try \XGAPCDOS.    */
  763.  
  764.             strcpy( font_path, "\\XGAPCDOS\\" );
  765.             strcat( font_path, font_file );
  766.  
  767.             font_fid = open( font_path, O_RDONLY | O_BINARY );
  768.         }
  769.     }
  770.  
  771.     if ( font_fid != -1 )
  772.     {
  773.         /* Calculate length of font file                            */
  774.  
  775.         font_file_len = ( word ) lseek( font_fid, 0L, SEEK_END );
  776.  
  777.         ffd_ptr = ( struct FontFileDefn * ) calloc( font_file_len, 1 );
  778.  
  779.  
  780.         /* read font file into memory                               */
  781.  
  782.         lseek( font_fid, 0L, SEEK_SET );
  783.  
  784.         read( font_fid, ( char * ) ffd_ptr, font_file_len );
  785.  
  786.  
  787.         /* Set up pointer to character set definition.        */
  788.  
  789.         csd_ptr = ( struct CharSetDef * ) ( ( char * ) ffd_ptr  +
  790.                             ffd_ptr->page_array[ ffd_ptr->def_page ].csd_offset );
  791.  
  792.  
  793.         /* Set up internal csd pointers                       */
  794.  
  795.         csd_ptr->chardef1 = ( byte far * ) ffd_ptr +  ( long )csd_ptr->chardef1;
  796.         csd_ptr->chardef2 = ( byte far * ) ffd_ptr +  ( long )csd_ptr->chardef2;
  797.         csd_ptr->chardef3 = ( byte far * ) ffd_ptr +  ( long )csd_ptr->chardef3;
  798.  
  799.         csd_ptr->indextbl = ( word far * ) ( ( byte far * )ffd_ptr  +
  800.                                                 ( long )csd_ptr->indextbl );
  801.  
  802.         csd_ptr->enveltbl = ( ( byte far * )ffd_ptr  + ( long )csd_ptr->enveltbl );
  803.  
  804.  
  805.         /* Finished with font file. */
  806.  
  807.         close( font_fid );
  808.  
  809.         cell_height = csd_ptr->cellheight;
  810.     }
  811.  
  812.     return csd_ptr;
  813. }